const isAndroid = window.navigator.userAgent.indexOf('Android') !== -1

function possNativeMessage(message) {
    if (isAndroid) {
        window.JSOriginBridge.postMessage(message);
    } else {
        window.webkit.messageHandlers.JSOriginBridge.postMessage(message);
    }
}

/* 向 Native 发布事件 */
function publishNativeMessage(params) {
    const message = {
        eventType: 'publish',
        data: params
    }
    possNativeMessage(message)
}

/* 触发 Native 方法, 触发回调函数 */
function invokeNativeEvent(name, params, callbackId) {
    const message = {
        eventType: 'invoke',
        type: name,
        data: params,
        callbackId
    }
    possNativeMessage(message)
}

class JSBridge {
    /* 保存 */
    eventHandlers = new Map()
    responseCallbacks = new Map()
    callbackID = 0
    constructor() {
        window._handleNativeCallback = this.handleNativeCallback.bind(this)
        window._handleNativeEvent = this.handleNativeEvent.bind(this)
    }
    /* 向 native 发送消息 */
    postMessage(params) {
        const data = JSON.stringify(params)
        publishNativeMessage(data)
    }
    /* 向 native 发送消息,等待回调函数 */
    invoke(name, payload, callback) {
        this.callbackID++
        /* 将回调函数保存起来 */
        this.responseCallbacks.set(this.callbackID, callback)
        invokeNativeEvent(name, payload, this.callbackID)
    }
    /* 
    处理 native 调用 window 上的 _handleNativeCallback 方法。
    当执行 invoke 回调的时候，执行该方法
    */
    handleNativeCallback(jsonResponse) {
        const res = JSON.parse(jsonResponse)
        const { callbackID, ...params } = res
        const callback = this.responseCallbacks.get(callbackID)
        /* 取出回调函数并且执行 */
        callback && callback(params)
        /* 删除对应的回调函数 */
        this.responseCallbacks.delete(callbackID)
    }
    /* 
     处理 native 调用 window 上的 _handleNativeEvent 方法。
     处理绑定在 native 的事件
     */
    handleNativeEvent(jsonResponse) {
        const res = JSON.parse(jsonResponse)
        const { eventName, ...params } = res
        const callback = this.eventHandlers.get(eventName)
        callback(params)
    }
    
    /* 绑定注册事件 */
    registerEvent(name, callback) {
        this.eventHandlers.set(name, callback)
    }
    /* 解绑事件 */
    unRegisterEvent(name) {
        this.eventHandlers.delete(name)
    }
}

export default new JSBridge()
